<?php
/**
 * UserModel handles the database interations for user & group actions
 *  
 * author: Chris Lunsford
 **/
class UserModel extends Model {
	
	function __construct() {
		parent::__construct();
		$this->load->helper('date');		
	}
	
	/**
	 * Creates a new user in the users db
	 * 
	 * @param string $post array containing user data
	 */
	function createUser($post) {
		$post['salt'] = sha1(mt_rand());
		$post['password'] = sha1($post['password'].$post['salt']);
		$this->db->insert('users',$post);
	}
	
	/**
	 * Return user ID based on username
	 * @return int/boolean Integer USERID if user exists, FALSE otherwise
	 */
	function getUserID($username) {
		$this->db->select('userid')->where('username', $username);
		$result = $this->db->get('users');
		return ($result->num_rows() == 1) ? $result->row()->userid : FALSE;
	}
	
	/**
	 * Tests to see if a username exists
	 * 
	 * @param string $username username to test
	 * @return bool TRUE if username exists, FALSE otherwise
	 */
	function isUsername($username) {
		$this->db->where('username', $username);
		$result = $this->db->get('users');
		return ($result->num_rows() == 1) ? TRUE : FALSE;
	}
	
	/**
	 * Saves time of user's last page load as a UNIX timestamp
	 *
	 * @param string $username username to update last activity
	 */
	function updateLastActivity($username) {
		$this->db->where('username', $username);
		$this->db->set('lastactivity', now());
		$this->db->update('users');
	}
	
	/**
	 * Saves time of user's last login as a datestamp
	 *
	 *
	 */
	function updateLastLogin($username) {
		$this->db->where('username', $username);
		$this->db->set('lastlogin', time());
		$this->db->update('users');
	}
	
	/**
	 * Validates login credentials against data in the database
	 *
	 * @param string $username Username used to login
	 * @param string $password password used to login
	 * @return bool TRUE if login credentials are valid, FALSE otherwise
	 */
	function validateLogin($username, $password) {
		if ($this->isUsername($username)) {
			$this->db->where('username', $username);
			$user = $this->db->get('users')->row();
			
			if ($user->salt != NULL) {
				$hash = sha1($password.$user->salt);
				return ($hash == $user->password) ? TRUE : FALSE;
			} else {
				//validate login, then salt them
				if ($user->password == sha1($password)) {
					//salt them and log them in
					$salt = sha1(mt_rand());
					$newPassword = sha1($password.$salt);
					$post['salt'] = $salt;
					$post['password'] = $newPassword;
					$this->updateUser($user->userid,$post);
					return TRUE;
				} else {
					return FALSE;
				}
			}
		} else {
			return FALSE;
		}
	}
	
	/**
	 * 
	 * @param string groupname to grab ID for
	 * @return int/boolean Int ID if group exists, FALSE otherwise
	 */
	function getGroupID($groupname) {
		$this->db->select('groupid')->from('groups')->where('groupname', $groupname);
		$result = $this->db->get();
		return ($result->num_rows() == 1) ? $result->row()->groupid : FALSE;
	}
	
	/**
	 * @param int userid
	 * @param int groupid
	 * @return bool TRUE if user is in group, FALSE if not
	 */
	function isUserInGroup($userid,$groupid) {
		$this->db->where('userid',$userid);
		$this->db->where('groupid',$groupid);
		return ($this->db->get('assigns')->num_rows() > 0) ? TRUE : FALSE;
	}
	
	/*******************************************************************
	 *                       User functions                            *
	 *******************************************************************/
	
	
	/**
	 * Deletes a user from the users db given the userid
	 * Note: this also deletes all user assignments to groups
	 *
	 * @param int $id userid of user to be deleted
	 */
	function deleteUser($id) {
		$this->db->where('userid', $id); 
		$this->db->delete('users');
		
		$this->db->where('userid', $id);
		$this->db->delete('assigns');
	}
	
	/**
	 * Updates user data in the users db
	 *
	 * @param array $post updated user data
	 */
	function updateUser($userid, $post) {
		$this->db->where('userid', $userid);
		$this->db->update('users',$post);
	}
	
	function updatePassword($userid, $newpass) {
		$user = $this->getUser($userid);
		//SALTED
		if ($user->salt != NULL) {
			$post['password'] = sha1($newpass.$user->salt);
		} else {
			$post['password'] = sha1($newpass);
		}
		
		$this->updateUser($userid, $post);
	}
	
	/**
	 * Returns all users with all fields
	 *
	 * @return array array containing all users with all fields
	 */
	function getUsers($order = 'username') {
		$this->db->orderby($order,'asc');
		return $this->db->get('users');
	}
	
	function getUsername($id) {
		$this->db->select('username')->where('userid', $id);
		$query = $this->db->get('users');
		$query = $query->row();
		return $query->username;
	}
			
	function getUser($id) {
		$this->db->where('userid',$id);
		return $this->db->get('users')->row();
	}
	
	function getUserByName($username) {
		$this->db->where('username',$username);
		$result = $this->db->get('users');
		
		if ($result->num_rows() > 1) {
			log_message('error','Duplicate usernames found in database!');
		} else {
			return $result->row();
		}
	}
	
	/**
	 * Gets a user based on an email address
	 * 
	 * @param string email address to check for
	 * @return user object if user exists, FALSE otherwise
	 */
	function getUserByEmail($email) {
		$this->db->where('email', $email);
		$result = $this->db->get('users');
		return ($result->num_rows() > 0) ? $result->row() : FALSE;
	}
	
	function getFullname($id) {
		$this->db->where('userid', $id);
		$user = $this->db->get('users')->row();
		return $user->firstname.' '.$user->lastname;
	}
	
	function getDisplayName($id) {
		$this->db->where('userid', $id);
		$user = $this->db->get('users')->row();
		if ($user) {
			if (!isset($user->display)) {
				if (!isset($user->firstname)) {
					return $user->username;
				} else {
					return $user->firstname.' '.substr($user->lastname,0,1);
				}
			} else {
				return $user->display;
			}
		} else {
			return "None";
		}
	}
	
	function getOnlineUsers() {
		$condition = now() - 300;
		$this->db->where('lastactivity >', $condition);
		return $this->db->get('users');
	}
	
	/*******************************************************************
	 *                       Group functions                           *
	 *******************************************************************/
	 
	/**
	 * Create a group in the groups db
	 *
	 * @param array $post array containing group data
	 */
	function createGroup($post) {
		$this->db->insert('groups',$post);
	}
	
	/**
	 * Delete a group from the groups db
	 * Note: this also deletes all user assignments to the group
	 *
	 * @param int $id groupid of group to be deleted
	 */
	function deleteGroup($id) {
		$this->db->where('groupid', $id); 
		$this->db->delete('groups');
		
		$this->db->where('groupid', $id);
		$this->db->delete('assigns');
	}
	
	function updateGroup($id, $post) {
		$this->db->where('groupid', $id);
		$this->db->update('groups',$post);
	}
		
	/**
	 * Tests to see if a groupname exists
	 * 
	 * @param string $groupname groupname to test
	 * @return bool TRUE if groupname exists, FALSE otherwise
	 */
	function isGroupname($groupname) {
		$this->db->where('groupname', $groupname);
		$result = $this->db->get('groups');
		return ($result->num_rows() == 1) ? TRUE : FALSE;
	}
	
	
	
	function getGroupname($id) {
		$this->db->select('groupname')->from('groups')->where('groupid', $id);
		return $this->db->get()->row()->groupname;
	}
	
	/**
	 * Get all groups with all group fields
	 *
	 * @return array all group data
	 */
	function getGroups() {
		return $this->db->get('groups');
	}
	
	function getGroup($groupid) {
		$this->db->where('groupid', $groupid);
		return $this->db->get('groups')->row();
	}
	
	function getGroupByName($groupname) {
		$this->db->where('groupname', $groupname);
		return $this->db->get('groups')->row();
	}
	
	function getMemberCount($groupid) {
		$this->db->where('groupid', $groupid);
		$result = $this->db->get('assigns');
		
		return $result->num_rows();
	}
	
	function getGroupMembers($groupid) {
		$this->db->where('groupid', $groupid);
		$this->db->orderby('rank','desc');
		$result = $this->db->get('assigns');
		
		if ($result->num_rows() > 0) {
			foreach ($result->result() as $row) {
				$row->user = $this->getUser($row->userid);
			}
			return $result;
		} else {
			return $result;
		}
	}
	/*******************************************************************
	 *                       Assign functions                          *
	 *******************************************************************/	 
	function getAssigns() {
		return $this->db->get('assigns');
	}
	
	function getUserAssigns($userid) {
		$this->db->where('userid', $userid);
		$result = $this->db->get('assigns');
		
		if ($result->num_rows() > 0) {
			foreach ($result->result() as $row) {
				$row->groupname = $this->getGroupname($row->groupid);
			}
			return $result;
		} else {
			return FALSE;
		}
	}
	
	function getGroupDescriptionsForUser($userid) {
		$this->db->where('userid', $userid);
		$result = $this->db->get('assigns');
		
		$groups = array();
		
		if ($result->num_rows() > 0) {
			foreach ($result->result() as $row) {
				$groups[] = $this->getGroup($row->groupid)->description;
			}
			return $groups;
		} else {
			return FALSE;
		}
	}
	
	function isLeader($userid, $groupid) {
		$this->db->where('userid', $userid);
		$this->db->where('groupid', $groupid);
		$this->db->where('rank', 1);
		$result = $this->db->get('assigns');
		return ($result->num_rows() < 1) ? FALSE : TRUE;
	}
	
	function getLeaders($groupid, $return = 'objects') {
		$this->db->where('groupid', $groupid);
		$this->db->where('rank', 1);
		$result = $this->db->get('assigns');
		
		if ($result->num_rows() < 1) {
			return "None";
		} else {
			if ($return == 'array') {
				foreach($result->result() as $row) {
					$array[] = $this->getUser($row->userid)->display;
				}
				return $array;
			} else {
				foreach($result->result() as $row) {
					$row->user = $this->getUser($row->userid);
				}
				return $result;
			}
		}
	}
	
	function getLeadersByName($groupid) {
		$this->db->where('groupid', $groupid);
		$this->db->where('rank', 1);
		$result = $this->db->get('assigns');
		
		foreach ($result->result() as $row) {
			$user = $this->getUser($row->userid);
			$row->name = $user->firstname.' '.$user->lastname;
		}
		
		return $result;
	}
	
	function assignUser($post) {
		$this->db->insert('assigns',$post);
	}
	
	function unassignUser($groupid,$userid) {
		$this->db->where('groupid',$groupid);
		$this->db->where('userid',$userid);
		$this->db->delete('assigns');
	}
	
	function updateRank($userid,$groupid,$rank) {
		$this->db->where('userid', $userid);
		$this->db->where('groupid',$groupid);
		$this->db->set('rank',$rank);
		$this->db->update('assigns');
	}
	
	function countUnsalted() {
		$where = 'salt IS NULL';
		$this->db->where($where);
		return $this->db->get('users')->num_rows();
	}
	
	function createToken($post) {
		$this->db->insert('cms_password_resets',$post);
	}
	
	function getToken($token) {
		$this->db->where('token', $token);
		return $this->db->get('cms_password_resets')->row();
	}
	
	function checkToken($token) {
		$this->db->where('token', $token);
		return ($this->db->get('cms_password_resets')->num_rows() == 1) ? TRUE : FALSE;
	}
	
	function deleteToken($token) {
		$this->db->where('token', $token);
		$this->db->delete('cms_password_resets');
	}
	
	/*
	 * Garbage collection for old Confirmation Tokens - for specific user
	 */
	function deleteOldTokens($userid) {
		$this->db->where('userid', $userid);
		$this->db->delete('cms_password_resets');
	}
	
	/*
	 * Garbage collection for expired Confirmation Tokens - for any user
	 */
	function deleteAllOldTokens() {
		$this->db->where('created <',time()-(60*60*72));
		$this->db->delete('cms_password_resets');
	}
}
?>